package com.yh.csx.bsf.flow.core.db;

import com.yh.csx.bsf.core.base.Callable;
import com.yh.csx.bsf.core.util.ContextUtils;
import com.yh.csx.bsf.flow.core.FlowProperties;
import lombok.val;
import lombok.var;

/**
 * @author: chejiangyi
 * @version: 2019-10-23 16:05
 **/
public class DbHelper {
    public static <T> T get(Callable.Func1<T,DbConn> action0){
        var db = connThreadLocal.get();
        if(db!=null)
        {
            return action0.invoke(db);
        }
        else {
            try (var db2 = new DbConn()) {
               return  action0.invoke(db2);
            }
        }
    }

    private static ThreadLocal<DbConn> connThreadLocal=new ThreadLocal<>();

    public static void call(Callable.Action1<DbConn> action0){
        Callable.Func1<Boolean,DbConn> action1 = (c)->{
            action0.invoke(c);
            return true;
        };
        get(action1);
    }

    public static void noTransactionCall(Callable.Action1<DbConn> action0){
        try (var db2 = new DbConn()) {
            action0.invoke(db2);
        }
    }
    public static <T> T noTransactionGet(Callable.Func1<T,DbConn> action0){
        try (var db2 = new DbConn()) {
            return action0.invoke(db2);
        }
    }


    public static void transaction(Callable.Action0 action0)
    {
        //事务嵌套
        if (connThreadLocal.get() != null)
        {
            action0.invoke();
        }
        else {
            DbConn db = null;
            try {
                val p = ContextUtils.getBean(FlowProperties.class, false);
                //boolean beginTransaction=false;
                if (p != null && p.getTransaction()) {
                    if (connThreadLocal.get() == null) {
                        connThreadLocal.set(new DbConn());
                        db = connThreadLocal.get();
                    }
                    db.beginTransaction(p.getLevel() > 0 ? p.getLevel() : 0);
                }
                action0.invoke();
                if (db != null) {
                    db.commit();
                }
            } catch (Exception e) {
                if (db != null) {
                    db.rollback();
                }
                throw e;
            } finally {
                if (db != null) {
                    db.close();
                    connThreadLocal.set(null);
                }
            }
        }
    }
}
